/*
* Copyright (c) 2007, Nubo Technologies
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
*    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*    * Neither the name of the Nubo Technologies nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package com.nubotech.gwt.oss.client.s3;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.HTTPRequest;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.ResponseTextHandler;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.XMLParser;
import com.nubotech.gwt.oss.client.*;
import com.nubotech.gwt.oss.client.auth.Credential;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author jonnakkerud
 */
public class MockS3OnlineStorageService extends OnlineStorageService {
    
    private static Document bucketDocument;
    private static Document aclDocument;
    private static Map content = new HashMap();
    
    public static List<Bucket> buckets = new ArrayList<Bucket>(); 
    
    /** Creates a new instance of MockFileSystem */
    public MockS3OnlineStorageService(Credential c) {
        super(c);
        if (bucketDocument == null) {
            HTTPRequest.asyncGet("buckets.xml", new ResponseTextHandler() {
                public void onCompletion(String responseText) {
                    bucketDocument = XMLParser.parse(responseText);
                }
            });
        }
        if (aclDocument == null) {
            HTTPRequest.asyncGet("acl.xml", new ResponseTextHandler() {
                public void onCompletion(String responseText) {
                    aclDocument = XMLParser.parse(responseText);
                }
            });            
        }
        if (content.size() == 0) {
            HTTPRequest.asyncGet("orders.xml", new ResponseTextHandler() {
                public void onCompletion(String responseText) {
                    content.put("orders", responseText);
                }
            });
            HTTPRequest.asyncGet("samples.xml", new ResponseTextHandler() {
                public void onCompletion(String responseText) {
                    content.put("samples-828ef3fdfa96f00ad9f27c383fc9ac7f", responseText);
                }
            });            
        }        
    }

    public void listAllBuckets(BucketResultCallback cb) {
        BucketHandler bh = new BucketHandler(cb);        
        // load the xml
        Document doc = getBucketDocument();
        bh.createBuckets(doc);
        if (buckets.size() > 0) {
            bh.bucketHolderResultList.addAll(buckets);
        }
        cb.onBucketResult(new BucketResult(bh.bucketHolderResultList, null));
    }

    public void createBucket(String name) {
        buckets.add(new Bucket(name));
    }

    public void deleteBucket(String name) {
    }

    public void setObject(String bucketName, String key, String data) {
    }

    private Document getBucketDocument() {
        return bucketDocument;
    }

    public void listBucket(String bucketName, ObjectHolderResultCallback cb) {
        String xml = (String) content.get(bucketName);
        if (xml != null) {
            Document doc = XMLParser.parse(xml);
            ObjectHolderListHandler bh = new ObjectHolderListHandler(cb);
            bh.createContent(doc);
            cb.onObjectHolderResult(new ObjectHolderResult(bh.objectHolderResultList, null));
        }
    }

    public void putObject(ObjectHolder content) {
        GWT.log(content.toStringExt(), null);
    }
    
    public void getObject(String bucketName, String key, ObjectHolderResultCallback cb) {
        ObjectHolder holder = new ObjectHolder();
        holder.setBucket(new Bucket(bucketName));
        holder.setKey(key);
        
        holder.setData("some random data for " + key + "\n" + "another line");

        cb.onObjectHolderResult(createResult(holder));
    }

    public void getObjectInfo(String bucketName, String key, ObjectHolderResultCallback cb) {
        ObjectHolder holder = new ObjectHolder();
        holder.setBucket(new Bucket(bucketName));
        holder.setKey(key);
        
        // add random meta data
        String s = String.valueOf(Random.nextInt()) + "-" + key;
        holder.addMetaData(s, "data");
 
        String s2 = String.valueOf(Random.nextInt()) + "-" + key;
        holder.addMetaData(s2, "data2");

        cb.onObjectHolderResult(createResult(holder));
    }

    public void deleteObject(String bucketName, String key) {
    }

    public void createBucket(String name, int accessPolicy) {
        GWT.log("createBucket " + name + " " + String.valueOf(accessPolicy), null);
    }

    // http://localhost:8888/com.nubotech.gwt.oss.browser.OSSBrowser/samples.xml
    public String createGetLink(String bucketName, String key, Date expires) {
        StringBuffer sb = new StringBuffer("http://");
        // build the path
        String path = nativeGetPath();
        path = path.substring(0, path.lastIndexOf("/"));       
        sb.append(nativeGetHost()).append("/").append(path).append("/samples.xml");        
        return sb.toString();
    }
    
    public static native String nativeGetHost() /*-{
        return $wnd.location.host;
    }-*/; 
    
    public static native String nativeGetPath() /*-{
        return $wnd.location.pathname;
    }-*/;     

    public void getAccessControlPolicy(String bucketName, AccessControlPolicyCallback cb) {
        AccessControlPolicyHandler handler = new AccessControlPolicyHandler(cb);
        handler.processAccessControlPolicy(aclDocument);
    }

    public void getAccessControlPolicy(String bucketName, String key, AccessControlPolicyCallback cb) {
        AccessControlPolicyHandler handler = new AccessControlPolicyHandler(cb);
        handler.processAccessControlPolicy(aclDocument);        
    }

    public void updateAccessControlPolicy(String bucketName, AccessControlPolicy policy) {
        AccessControlPolicySerializer policySerializer = new AccessControlPolicySerializer(policy);
        GWT.log(policySerializer.toXml(), null);
    }

    public void updateAccessControlPolicy(String bucketName, String key, AccessControlPolicy policy) {
        AccessControlPolicySerializer policySerializer = new AccessControlPolicySerializer(policy);
        GWT.log(policySerializer.toXml(), null);
    }

    public void beginBatch() {
    }

    public void commitBatch() {
    }

    public void listBucket(String bucketName, Map params, ObjectHolderResultCallback cb) {
        // get content for the bucket
        //ObjectHolderListHandler handler = new ObjectHolderListHandler(cb);
        //handler.createContent(aclDocument);
        
        String prefix = params != null ? (params.containsKey("prefix") ? (String) params.get("prefix") : null) : null;
        
        String xml = (String) content.get(bucketName);
        if (xml != null) {
            Document doc = XMLParser.parse(xml);
            ObjectHolderListHandler bh = new ObjectHolderListHandler(cb);
            bh.createContent(doc);
            
            List filterList = new ArrayList();
            
            if (prefix != null) {
            for (ObjectHolder oh : bh.objectHolderResultList) {
                if (oh.getKey().startsWith(prefix)) {
                    filterList.add(oh);
                }
            }
            }
            else {
                filterList.addAll(bh.objectHolderResultList);
            }
            
            cb.onObjectHolderResult(new ObjectHolderResult(filterList, null));
        }
       
        
        // filter by prefx
        
    }

    public void getObject(String bucketName, String key, RequestHeader[] headers, ObjectHolderResultCallback cb) {
    }

    public void putObject(ObjectHolder content, RequestHeader[] headers) {
    }
    
    private static ObjectHolderResult createResult(ObjectHolder holder) {
        List l = new ArrayList();
        l.add(holder);
        return new ObjectHolderResult(l, null);
    }

    @Override
    public void setHost(String host) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public String getHost() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    
}
